/**
 * actualiza o planeamento dos tecnicos de acordo com a alocação de tarefas feitas
**/
void actualizarTecnicos(){
}

/**
 * limpa as alocacoes temporarias  feitas durante a tentativa de alocacao de um pedido
 **/
void libertarAplicacoesTemporarias(){	
}

/**
 * tenta alocar a tarefa a uma determinada hora a um funcionario com competencias suficientes
 * @return false - n„o alocou a tarefa
 * @return true - alocou a tarefa
**/ 
bool alocarTarefa(Tarefa tarefa, date hora_actual, int id_cliente_associado){
	int nivel = tarefa.getNivelMinimo();
	while(nivel <= 5) {
		foreach(Tecnico tecnico in tecnicos) {
			// se o tecnico tiver qualificacoes suficientes e puder alocar a tarefa nessa hora
			if ( (tecnico.getNivel() >= nivel) && (!tecnico.getPlaneamento().get(hora_actual)) ) {
				tarefa.setIdClienteAssociado(id_cliente_associado);
				alocacoes_temporarias.Add(tecnico.getId(), planeamento.Add(hora_actual, tarefa));
				return true;
			}
		}
		nivel++;
	}
	return false;
}

/**
 * #define hora_inicio 9h
 * #define hora_fim 18h
 * @param tarefa_actual = 0 no inicio
 * @return true se alocou pedido
 * @return false se nao alocou pedido
**/
bool alocarPedido(int tarefa_actual, date hora_actual, date hora_primeira_tarefa, Pedido pedido){
	int duracao_pedido = pedido.getDuracao();
	Tarefa tarefa = pedido.getTarefas().get(tarefa_actual);
	
	
	if( tarefa  && (hora_primeira_tarefa+duracao_pedido <= hora_fim) ){
		
			if( alocarTarefa(tarefa, hora_actual) ) {
				horaActual = horaActual+tarefa.getDuracao();
				alocarPedido(++tarefa_actual, horaActual, hora_primeira_tarefa, pedido);
			}
			else {
				libertarAlocacoesTemporarias();
				hora_primeira_tarefa++;
				alocarPedido(0, hora_primeira_tarefa, hora_primeira_tarefa, pedido);					
			}
			
	} 
	if (hora_primeira_tarefa+duracao_pedido > hora_fim) {
		libertarAlocacoesTemporarias();
		return false;
	}
	return true;
}

void alocarPedidos(HashSet<Pedido> lista_pedidos){
	
	foreach(Pedido pedido : lista_pedidos){
		
		if(alocarPedido(0, hora_inicio, hora_inicio, pedido)==true){ 
					actualizarTecnicos();
					pedidos.get(pedido.getId()).setAlocado(true);
		}
		else{ 
	  	 		pedidos.get(pedido.getId()).setAdiado(true);
					pedidos.get(pedido.getId()).setPrioridade(pedidos.get(pedido.getId()).getPrioridade()--);
	  }	
	  
	}	
	
}	


void escalonar(){
	
	HashSet<Pedido> lista_pedidos_adiados, lista_pedidos_P1, lista_pedidos_P2, lista_pedidos_P3;
	
	foreach(Pedido pedido : pedidos){
		if(pedido.getAlocado()==true)
			lista_pedidos_adiados.Add(pedido);
		else
			if(pedido.getPrioridade==1)
				lista_pedidos_P1.Add(pedido);
			else
				if(pedido.getPrioridade==2)
				lista_pedidos_P2.Add(pedido);	
				else
					if(pedido.getPrioridade==3)
						lista_pedidos_P3.Add(pedido);	
	}
	
	alocarPedidos(lista_pedidos_adiados);
	alocarPedidos(lista_pedidos_P1);
	alocarPedidos(lista_pedidos_P2);
	alocarPedidos(lista_pedidos_P3);

}		